-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[Windows] Fix plugin registry symbols not exported/linked with CLANG_LINK_CLANG_DYLIB #163391
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…LINK_CLANG_DYLIB When building LLVM with CLANG_LINK_CLANG_DYLIB=ON on Windows, external plugins cannot register through llvm::Registry<clang::PluginASTAction> due to two issues: 1. Static data members (Head, Tail) are filtered out during symbol export 2. Static methods (add_node(), begin()) are not linked into the executable This change fixes both issues: - Modified extract_symbols.py to recognize and export Registry<T>::Head and Registry<T>::Tail static members using pattern matching instead of filtering them out as non-function symbols. - Added code in driver.cpp that references Registry methods, forcing the linker to include these symbols in clang.exe even though they're not directly called by the driver. Fixes llvm#163367
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-clang Author: None (zond) ChangesWhen building LLVM with CLANG_LINK_CLANG_DYLIB=ON on Windows, external plugins cannot register through llvm::Registry<clang::PluginASTAction> due to two issues:
This change fixes both issues:
Fixes #163367 Full diff: https://github.com/llvm/llvm-project/pull/163391.diff 2 Files Affected:
diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index 7390d7d610ec0..855c8285e841c 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -55,6 +55,25 @@
#include <set>
#include <system_error>
+#if defined(CLANG_PLUGIN_SUPPORT) && defined(_WIN32)
+#include "clang/Frontend/FrontendPluginRegistry.h"
+
+// Force plugin registry symbols into clang.exe on Windows so plugins can
+// register. These methods exist in libraries but aren't linked by default
+// because they're unreferenced. Taking their addresses forces the linker to
+// include them.
+namespace {
+void ForcePluginRegistrySymbols() {
+ using PluginRegistry = llvm::Registry<clang::PluginASTAction>;
+ // Use volatile to prevent the compiler from optimizing away these references
+ volatile auto add_node_ptr = &PluginRegistry::add_node;
+ volatile auto begin_ptr = &PluginRegistry::begin;
+ (void)add_node_ptr;
+ (void)begin_ptr;
+}
+} // anonymous namespace
+#endif
+
using namespace clang;
using namespace clang::driver;
using namespace llvm::opt;
diff --git a/llvm/utils/extract_symbols.py b/llvm/utils/extract_symbols.py
index 388723421d660..72f992f560c7f 100755
--- a/llvm/utils/extract_symbols.py
+++ b/llvm/utils/extract_symbols.py
@@ -105,6 +105,11 @@ def should_keep_microsoft_symbol(symbol, calling_convention_decoration):
# Skip X86GenMnemonicTables functions, they are not exposed from llvm/include/.
elif re.match(r"\?is[A-Z0-9]*@X86@llvm", symbol):
return None
+ # Keep Registry<T>::Head and Registry<T>::Tail static members for plugin support.
+ # Pattern matches: ?Head@?$Registry@<template_args>@llvm@@ or ?Tail@?$Registry@...
+ elif ("?$Registry@" in symbol and "@llvm@@" in symbol and
+ (symbol.startswith("?Head@") or symbol.startswith("?Tail@"))):
+ return symbol
# Keep mangled llvm:: and clang:: function symbols. How we detect these is a
# bit of a mess and imprecise, but that avoids having to completely demangle
# the symbol name. The outermost namespace is at the end of the identifier
|
… fixes r=glandium This change adds support for building Firefox with Clang 20, including critical fixes for the clang-plugin dynamic linking on Windows. Clang 20 introduced two breaking changes that prevented the clang-plugin from loading on Windows: 1. The CLANG_ABI macro was added to Attr classes, causing inline methods like classof() and getAnnotation() to generate dllimport references. This fails because these methods are defined inline in headers, not exported from the DLL. 2. The extract_symbols.py script became more aggressive in filtering symbols, blocking Registry<T> static data members (Head/Tail) that don't match function signature patterns. The fix consists of three patches for the Clang 20 build: - add-plugin-symbols_clang_20.patch: Adds pattern matching to extract_symbols.py to recognize and export Registry<T>::Head and ::Tail static members for any Registry instantiation. This replaces the need for hardcoded symbol whitelists and works across different plugin types. See llvm/llvm-project#163367 and llvm/llvm-project#163391. - force-plugin-symbols_clang_20.patch: Adds C++ code to driver.cpp that references Registry<PluginASTAction>::add_node() and ::begin() to force the linker to include these symbols. This replaces hardcoded mangled symbol names with type-safe references that work across compiler versions. See llvm/llvm-project#163367 and llvm/llvm-project#163391. - remove-clang-abi-from-attrs_clang_20.patch: Removes the CLANG_ABI macro from Attr class generation to prevent dllimport issues with inline methods. See llvm/llvm-project#163349. To test this locally: - Install the current clang-20 inside the firefox checkout: `./mach artifact toolchain --from-build win64-clang-20` - Install libxml2 (necessary for clang-mt.exe): `./mach artifact toolchain --from-build win64-libxml2` - Install wasm32-wasi-compiler-rt-20 (necessary for WASM compilation?): `./mach artifact toolchain --from-build wasm32-wasi-compiler-rt-20` - Check out llvm 20.1.8 in a directory alongside the firefox checkout. - Try to build llvm, and fail when the wasi lib is missing: `MOZ_FETCHES_DIR=../firefox python3 ../firefox/build/build-clang/build-clang.py -c ../firefox/build/build-clang/use-clang-cl-artifact.json -c ../firefox/build/build-clang/win64.json -c ../firefox/build/build-clang/clang-20.json -c ../firefox/build/build-clang/2stages.json` - Copy the missing wasi lib to the stage2 build directory: ``` mkdir build/stage2/clang/lib/clang/20/lib/wasm32-unknown-wasi cp ../firefox/compiler-rt-wasm32-wasi/lib/wasi/libclang_rt.builtins-wasm32.a build/stage2/clang/lib/clang/20/lib/wasm32-unknown-wasi/libclang_rt.builtins.a ``` - Try to build llvm again and succeed: `MOZ_FETCHES_DIR=../firefox python3 ../firefox/build/build-clang/build-clang.py -c ../firefox/build/build-clang/use-clang-cl-artifact.json -c ../firefox/build/build-clang/win64.json -c ../firefox/build/build-clang/clang-20.json -c ../firefox/build/build-clang/2stages.json` - Update the mozconfig in the firefox checkout to turn on the clang plugin and use the right compiler: ``` export CC=[THE LLVM CHECKOUT DIRECTORY]/build/stage2/clang/bin/clang-cl.exe ac_add_options --enable-clang-plugin ``` - Build firefox: `./mach clobber && ./mach configure --enable-bootstrap=no-update && ./mach build` Differential Revision: https://phabricator.services.mozilla.com/D268255
… fixes r=glandium This change adds support for building Firefox with Clang 20, including critical fixes for the clang-plugin dynamic linking on Windows. Clang 20 introduced two breaking changes that prevented the clang-plugin from loading on Windows: 1. The CLANG_ABI macro was added to Attr classes, causing inline methods like classof() and getAnnotation() to generate dllimport references. This fails because these methods are defined inline in headers, not exported from the DLL. 2. The extract_symbols.py script became more aggressive in filtering symbols, blocking Registry<T> static data members (Head/Tail) that don't match function signature patterns. The fix consists of two patches for the Clang 20 build: - plugin-registry-symbols_clang_20-llvm-pr-163391.patch: Make extract_symbols.py recognize and export Registry<T>::Head and ::Tail static members for any Registry instantiation. References Registry<PluginASTAction>::add_node() and ::begin() to force the linker to include these symbols. See llvm/llvm-project#163367 and llvm/llvm-project#163391. - remove-clang-abi-from-attrs_clang_20.patch: Removes the CLANG_ABI macro from Attr class generation to prevent dllimport issues with inline methods in Windows. See llvm/llvm-project#163349. To test this locally: - Install the current clang-20 inside the firefox checkout: `./mach artifact toolchain --from-build win64-clang-20` - Install libxml2 (necessary for clang-mt.exe): `./mach artifact toolchain --from-build win64-libxml2` - Install wasm32-wasi-compiler-rt-20 (necessary for WASM compilation?): `./mach artifact toolchain --from-build wasm32-wasi-compiler-rt-20` - Check out llvm 20.1.8 in a directory alongside the firefox checkout. - Try to build llvm, and fail when the wasi lib is missing: `MOZ_FETCHES_DIR=../firefox python3 ../firefox/build/build-clang/build-clang.py -c ../firefox/build/build-clang/use-clang-cl-artifact.json -c ../firefox/build/build-clang/win64.json -c ../firefox/build/build-clang/clang-20.json -c ../firefox/build/build-clang/2stages.json` - Copy the missing wasi lib to the stage2 build directory: ``` mkdir build/stage2/clang/lib/clang/20/lib/wasm32-unknown-wasi cp ../firefox/compiler-rt-wasm32-wasi/lib/wasi/libclang_rt.builtins-wasm32.a build/stage2/clang/lib/clang/20/lib/wasm32-unknown-wasi/libclang_rt.builtins.a ``` - Try to build llvm again and succeed: `MOZ_FETCHES_DIR=../firefox python3 ../firefox/build/build-clang/build-clang.py -c ../firefox/build/build-clang/use-clang-cl-artifact.json -c ../firefox/build/build-clang/win64.json -c ../firefox/build/build-clang/clang-20.json -c ../firefox/build/build-clang/2stages.json` - Update the mozconfig in the firefox checkout to turn on the clang plugin and use the right compiler: ``` export CC=[THE LLVM CHECKOUT DIRECTORY]/build/stage2/clang/bin/clang-cl.exe ac_add_options --enable-clang-plugin ``` - Build firefox: `./mach clobber && ./mach configure --enable-bootstrap=no-update && ./mach build` Differential Revision: https://phabricator.services.mozilla.com/D268255
… fixes r=glandium This change adds support for building Firefox with Clang 20, including critical fixes for the clang-plugin dynamic linking on Windows. Clang 20 introduced two breaking changes that prevented the clang-plugin from loading on Windows: 1. The CLANG_ABI macro was added to Attr classes, causing inline methods like classof() and getAnnotation() to generate dllimport references. This fails because these methods are defined inline in headers, not exported from the DLL. 2. The extract_symbols.py script became more aggressive in filtering symbols, blocking Registry<T> static data members (Head/Tail) that don't match function signature patterns. The fix consists of two patches for the Clang 20 build: - plugin-registry-symbols_clang_20-llvm-pr-163391.patch: Make extract_symbols.py recognize and export Registry<T>::Head and ::Tail static members for any Registry instantiation. References Registry<PluginASTAction>::add_node() and ::begin() to force the linker to include these symbols. See llvm/llvm-project#163367 and llvm/llvm-project#163391. - remove-clang-abi-from-attrs_clang_20.patch: Removes the CLANG_ABI macro from Attr class generation to prevent dllimport issues with inline methods in Windows. See llvm/llvm-project#163349. Differential Revision: https://phabricator.services.mozilla.com/D268255
… fixes r=glandium This change adds support for building Firefox with Clang 20, including critical fixes for the clang-plugin dynamic linking on Windows. Clang 20 introduced two breaking changes that prevented the clang-plugin from loading on Windows: 1. The CLANG_ABI macro was added to Attr classes, causing inline methods like classof() and getAnnotation() to generate dllimport references. This fails because these methods are defined inline in headers, not exported from the DLL. 2. The extract_symbols.py script became more aggressive in filtering symbols, blocking Registry<T> static data members (Head/Tail) that don't match function signature patterns. The fix consists of two patches for the Clang 20 build: - plugin-registry-symbols_clang_20-llvm-pr-163391.patch: Make extract_symbols.py recognize and export Registry<T>::Head and ::Tail static members for any Registry instantiation. References Registry<PluginASTAction>::add_node() and ::begin() to force the linker to include these symbols. See llvm/llvm-project#163367 and llvm/llvm-project#163391. - remove-clang-abi-from-attrs_clang_20.patch: Removes the CLANG_ABI macro from Attr class generation to prevent dllimport issues with inline methods in Windows. See llvm/llvm-project#163349. Differential Revision: https://phabricator.services.mozilla.com/D268255
… fixes r=glandium This change adds support for building Firefox with Clang 20, including critical fixes for the clang-plugin dynamic linking on Windows. Clang 20 introduced two breaking changes that prevented the clang-plugin from loading on Windows: 1. The CLANG_ABI macro was added to Attr classes, causing inline methods like classof() and getAnnotation() to generate dllimport references. This fails because these methods are defined inline in headers, not exported from the DLL. 2. The extract_symbols.py script became more aggressive in filtering symbols, blocking Registry<T> static data members (Head/Tail) that don't match function signature patterns. The fix consists of two patches for the Clang 20 and trunk builds: - plugin-registry-symbols-llvm-pr-163391.patch: Make extract_symbols.py recognize and export Registry<T>::Head and ::Tail static members for any Registry instantiation. References Registry<PluginASTAction>::add_node() and ::begin() to force the linker to include these symbols. See llvm/llvm-project#163367 and llvm/llvm-project#163391. - remove-clang-abi-from-attrs-clang-[20|trunk].patch: Removes the CLANG_ABI macro from Attr class generation to prevent dllimport issues with inline methods in Windows. See llvm/llvm-project#163349. Differential Revision: https://phabricator.services.mozilla.com/D268255
… fixes r=glandium This change adds support for building Firefox with Clang 20, including critical fixes for the clang-plugin dynamic linking on Windows. Clang 20 introduced two breaking changes that prevented the clang-plugin from loading on Windows: 1. The CLANG_ABI macro was added to Attr classes, causing inline methods like classof() and getAnnotation() to generate dllimport references. This fails because these methods are defined inline in headers, not exported from the DLL. 2. The extract_symbols.py script became more aggressive in filtering symbols, blocking Registry<T> static data members (Head/Tail) that don't match function signature patterns. The fix consists of two patches for the Clang 20 and trunk builds: - plugin-registry-symbols-llvm-pr-163391.patch: Make extract_symbols.py recognize and export Registry<T>::Head and ::Tail static members for any Registry instantiation. References Registry<PluginASTAction>::add_node() and ::begin() to force the linker to include these symbols. See llvm/llvm-project#163367 and llvm/llvm-project#163391. - remove-clang-abi-from-attrs-clang-[20|trunk].patch: Removes the CLANG_ABI macro from Attr class generation to prevent dllimport issues with inline methods in Windows. See llvm/llvm-project#163349. Differential Revision: https://phabricator.services.mozilla.com/D268255
When building LLVM with CLANG_LINK_CLANG_DYLIB=ON on Windows, external plugins cannot register through llvm::Registryclang::PluginASTAction due to two issues:
This change fixes both issues:
Modified extract_symbols.py to recognize and export Registry::Head and Registry::Tail static members using pattern matching instead of filtering them out as non-function symbols.
Added code in driver.cpp that references Registry methods, forcing the linker to include these symbols in clang.exe even though they're not directly called by the driver.
Fixes #163367